home *** CD-ROM | disk | FTP | other *** search
- /*
- * file file.c:
- *
- * The routines in this file
- * handle the reading and writing of
- * disk files. All of details about the
- * reading and writing of the disk are
- * in "fileio.c".
- */
- #include <stdio.h>
- #include "ed.h"
-
- #if AtST
- /* overlay "me2" dal: not available in Alcyon C */
- #endif
-
- /*
- * Read a file into the current
- * buffer. This is really easy; all you do it
- * find the name of the file, and call the standard
- * "read a file into the current buffer" code.
- * Bound to "C-X C-R". mb: added keep&insert stuff.
- */
- fileread(f, n)
- {
- register BUFFER *bp;
- register int s, ins;
- char fname[NFILEN];
-
- bp = curbp;
- if (lforw(bp->b_linep) != bp->b_linep) /* buf not empty */
- {
- ins = mlyesno("Keep current text");
- if (ins == ABORT)
- {
- mlwrite("[aborted]");
- return (ABORT);
- }
- if (ins != TRUE)
- {
- if ((s=bclear(bp)) != TRUE)
- return (s);
- }
- }
- else
- ins = FALSE;
- if ((s=mlgetfn("File to read", fname, NFILEN)) != TRUE)
- return (s);
- if ((s=readin(fname)) != FIOEOF)
- return (FALSE);
- bp->b_flag &= ~BFTEMP;
- if (ins)
- bp->b_flag |= BFCHG;
- else
- {
- fullpath(bp->b_fname, fname); /* dal: normalize */
- bp->b_flag &= ~BFCHG;
- }
- bp->b_flag |= BFEDIT; /* read for editing */
- return (TRUE);
- }
-
- /*
- * Select a file for editing.
- * Look around to see if you can find the
- * fine in another buffer; if you can find it
- * just switch to the buffer. If you cannot find
- * the file, create a new buffer, read in the
- * text, and switch to the new buffer.
- * Bound to C-X C-V.
- * mb: combined "out" portion of new & old cases.
- */
- filevisit(f, n)
- {
- register BUFFER *bp;
- register WINDOW *wp;
- register LINE *lp;
- register int i;
- register int s;
- char bname[NBUFN];
- char fname[NFILEN];
- char *msg;
- int old = FALSE;
-
- if ((s=mlgetfn("File to visit", fname, NFILEN)) != TRUE)
- return (s);
- fullpath(fname, fname); /* dal: added */
- for (bp=bheadp; bp!=NULL; bp=bp->b_bufp)
- {
- if ((bp->b_flag&BFTEMP)==0 && strcmp(bp->b_fname, fname)==0)
- {
- old = TRUE;
- break;
- }
- }
- if (old) goto out;
-
- makename(bname, fname); /* New buffer name. */
- while ((bp=bfind(bname, FALSE, 0)) != NULL)
- {
- s = mlgets("Buffer name", "default: existing buffer!",
- bname, NBUFN, CRLF);
- if (s == ABORT) /* ^G to just quit */
- return (ABORT);
- if (bname[0] == '\0') /* CR to clobber it */
- {
- if (bclear(bp) != TRUE)
- return (FALSE);
- makename(bname, fname);
- break;
- }
- }
- if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL)
- {
- mlwrite("Cannot create buffer");
- return (FALSE);
- }
-
- out:
- gotobuf(bp); /* mb: in buffer.c */
- curwp->w_linep = bp->b_linep;
- curwp->w_flag |= WFMODE|WFFORCE|WFHARD;
- if (old)
- mlwrite("[Old buffer]");
- else
- {
- if ((s=readin(fname)) != FIOEOF)
- {
- gotobuf(oldbp); /* back where we started */
- freebuf(oldbp); /* now oldbp = abandoned */
- return (FALSE); /* (empty) visited buf */
- }
- fullpath(bp->b_fname, fname); /* dal: normalize */
- bp->b_flag &= ~(BFTEMP|BFCHG);
- }
- bp->b_flag &= ~BFEDIT; /* visit for viewing */
- return (TRUE);
- }
-
- /*
- * Read file "fname" into the current buffer.
- * Called by both the read and visit commands.
- * Return the final status of the read.
- * Also called by the mainline, to read in a file
- * specified on the command line as an argument.
- */
- readin(fname)
- char fname[];
- {
- register LINE *lp1;
- register char *cp;
- register int i;
- register int nbytes;
- register int nline;
- register int s;
- WINDOW *wp;
- BUFFER *bp;
- LINE *lp2;
- LINE *flp;
- char line[NLINE];
- int longline = FALSE;
-
- s = ffropen(fname);
- if (s == FIOERR)
- mlwrite("Error opening file");
- if (s == FIOFNF)
- mlwrite("File not found");
- if (s != FIOSUC)
- return (s);
- mlwrite("[Reading file...]");
- bp = curbp;
- flp = lforw(bp->b_linep);
- nline = 0;
- while (((s=ffgetline(line, NLINE)) == FIOSUC ) || (s==FIOFNF))
- {
- /* dal: FNF indicates no nl at eof. save last line and exit. */
-
- nbytes = strlen(line);
- if (nbytes == NLINE-1) /* "long line" */
- longline = TRUE; /* Keep message */
- if ((lp1=lnalloc(nbytes)) == NULL)
- {
- s = FIOERR; /* Keep message on the */
- break; /* display. */
- }
-
- /* mb: original version:
-
- lp2 = lback(curbp->b_linep);
- lp2->l_fp = lp1;
- lp1->l_fp = curbp->b_linep;
- lp1->l_bp = lp2;
- curbp->b_linep->l_bp = lp1;
- for (i=0; i<nbytes; i++)
- lputc(lp1, i, line[i]);
-
- - instead, enable insertion into existing text: */
-
- if (nline == 0)
- flp = lp1;
- lp2 = lback(curwp->w_dotp);
- lp2->l_fp = lp1;
- lp1->l_fp = curwp->w_dotp;
- lp1->l_bp = lp2;
- curwp->w_dotp->l_bp = lp1;
- cp = line;
- for (i=0; i<nbytes; i++)
- lputc(lp1, i, *cp++);
-
- nline++;
- }
- frclose(); /* Ignore errors. */
- if (s==FIOEOF && (! longline)) /* Don't zap message! */
- mlwrite("[Read %d line(s)]", nline);
- for (wp=wheadp; wp!=NULL; wp=wp->w_wndp)
- {
- if (wp->w_bufp == curbp)
- {
- /* original: wp->w_linep = lforw(curbp->b_linep);
- wp->w_dotp = lforw(curbp->b_linep);
- wp->w_doto = 0;
-
- - mb: */ wp->w_linep = flp;
- wp->w_dotp = flp;
- wp->w_doto = 0;
- wp->w_force = 0;
- wp->w_flag |= WFMODE|WFHARD|WFFORCE;
- wp->w_markp = NULL;
- wp->w_marko = 0;
- }
- }
- /* dal: FNF indicates no nl at eof. fix return code and then exit. */
- if(s == FIOFNF)
- s = FIOEOF;
-
- return (s);
- }
-
- /*
- * Take a file name, and from it
- * fabricate a buffer name. This routine knows
- * about the syntax of file names on the target system.
- * I suppose that this information could be put in
- * a better place than a line of code.
- */
- makename(bname, fname)
- char bname[];
- char fname[];
- {
- register char *cp1;
- register char *cp2;
- register char c;
-
- #if !AtST
- /* NOTE: be sure that your implementation of strrchr() will
- correctly locate the terminating '\0' as needed here. */
- cp1 = strrchr(fname, '\0');
- #endif
- #if VMS
- while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']')
- --cp1;
- #endif
- #if CPM
- while (cp1!=&fname[0] && cp1[-1]!=':')
- --cp1;
- #endif
- #if MSDOS
- while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\')
- --cp1;
- #endif
- #if AtST
- if((cp1 = strrpbrk(fname, ":\\")) == NULL)
- cp1 = fname;
- else
- ++cp1;
- #endif
- #if V7
- while (cp1!=&fname[0] && cp1[-1]!='/')
- --cp1;
- #endif
- strcpy(bname, cp1); /* copy tail of file name */
- strlwr(bname); /* lowercase the string */
- }
-
- /*
- * Ask for a file name, and write the
- * contents of the current buffer to that file.
- * Update the remembered file name and clear the
- * buffer changed flag. This handling of file names
- * is different from the earlier versions, and
- * is more compatible with Gosling EMACS than
- * with ITS EMACS. Bound to "C-X C-W".
- * mb: added default filename.
- */
- filewrite(f, n)
- {
- register char *cp1;
- register int c;
- int s;
- char fname[NFILEN];
- WINDOW *wp;
-
- cp1 = curbp->b_fname;
- if(*cp1 == '\0')
- cp1 = NULL;
-
- if ((s=mlgets("File to write", cp1, fname, NFILEN, CRLF)) == ABORT)
- return (s);
- if (fname[0] == '\0')
- fullpath(fname, curbp->b_fname);
-
- if ((s=writeout(fname)) == TRUE)
- {
- fullpath(curbp->b_fname, fname);
- curbp->b_flag &= ~BFCHG;
- wp = wheadp; /* Update mode lines. */
- while (wp != NULL)
- {
- if (wp->w_bufp == curbp)
- wp->w_flag |= WFMODE;
- wp = wp->w_wndp;
- }
- }
- return (s);
- }
-
- /*
- * Save the contents of the current
- * buffer in its associatd file. Do nothing
- * if nothing has changed (this may be a bug, not a
- * feature). Error if there is no remembered file
- * name for the buffer. Bound to "C-X C-S". May
- * get called by "C-Z".
- */
- filesave(f, n)
- {
- register WINDOW *wp;
- register int s;
-
- if ((curbp->b_flag&BFCHG) == 0) /* Return, no changes. */
- return (TRUE);
- if (curbp->b_fname[0] == 0) /* Must have a name. */
- {
- mlwrite("No file name");
- return (FALSE);
- }
- if ((s=writeout(curbp->b_fname)) == TRUE)
- {
- curbp->b_flag &= ~BFCHG;
- wp = wheadp; /* Update mode lines. */
- while (wp != NULL)
- {
- if (wp->w_bufp == curbp)
- wp->w_flag |= WFMODE;
- wp = wp->w_wndp;
- }
- }
- return (s);
- }
-
- /*
- * This function performs the details of file
- * writing. Uses the file management routines in the
- * "fileio.c" package. The number of lines written is
- * displayed. Sadly, it looks inside a LINE; provide
- * a macro for this. Most of the grief is error
- * checking of some sort.
- */
- writeout(fn)
- char *fn;
- {
- register int s;
- register LINE *lp;
- register int nline;
-
- s = ffwopen(fn);
- if (s != FIOSUC)
- {
- mlwrite("Cannot open file for writing");
- return (FALSE);
- }
-
- mlwrite("[writing file...]");
- lp = lforw(curbp->b_linep); /* First line. */
- nline = 0; /* Number of lines. */
- while (lp != curbp->b_linep)
- {
- if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
- break;
- ++nline;
- lp = lforw(lp);
- }
- if (s == FIOSUC) /* No write error. */
- {
- s = fwclose();
- if (s == FIOSUC) /* No close error. */
- {
- mlwrite("[Wrote %d line(s)]", nline);
- }
- }
- else /* Ignore close error */
- fwclose(); /* if a write error. */
- if (s != FIOSUC) /* Some sort of error. */
- return (FALSE);
- return (TRUE);
- }
-
- /*
- * The command allows the user
- * to modify the file name associated with
- * the current buffer. It is like the "f" command
- * in UNIX "ed". The operation is simple; just zap
- * the name in the BUFFER structure, and mark the windows
- * as needing an update.
- */
- filename(f, n)
- {
- register WINDOW *wp;
- register int s;
- char fname[NFILEN];
-
- if ((s=mlgetfn("New filename", fname, NFILEN)) != TRUE)
- return (s);
- fullpath(curbp->b_fname, fname);
- curbp->b_flag |= BFCHG;
- wp = wheadp; /* Update mode lines. */
- while (wp != NULL)
- {
- if (wp->w_bufp == curbp)
- wp->w_flag |= WFMODE;
- wp = wp->w_wndp;
- }
- return (TRUE);
- }
-
-
- /*
- * file fileio.c:
- *
- * mb: Atari ST stuff & BFILES added.
- *
- * The routines in this file
- * read and write ASCII files from the
- * disk. All of the knowledge about files
- * are here. A better message writing
- * scheme should be used.
- */
-
- static FILE *ffp; /* File pointer, all functions. */
- #if BFILES
- static char fbufp[FBLOCK]; /* File text buffer */
- static char *fbpos; /* Current position in file text buffer */
- static char *ftail; /* End of file text buffer */
- #if AtST
- static int hndl = 0; /* dal: variable was called "handle" */
- #endif
- #endif BFILES
-
- /*
- * Open a file for reading.
- */
- ffropen(fn)
- char *fn;
- {
- #if BFILES
-
- #if AtST
- register int i;
-
- if ((i = open(fn, O_RDONLY)) < 0)
- return ((i == -33) ? FIOFNF : FIOERR);
- hndl = i;
- fbpos = fbufp;
- ftail = fbufp; /* nothing read yet */
- return (FIOSUC);
- #else
- return (FIOERR);
- #endif
-
- #else /* if not BFILES */
-
- #if AtST|MSDOS
- if ((ffp=fopen(fn, "rb")) == NULL) /* we handle crlf ourselves */
- #else
- if ((ffp=fopen(fn, "r")) == NULL)
- #endif
- return (FIOFNF);
- return (FIOSUC);
- #endif BFILES
- }
-
- /*
- * Open a file for writing.
- * Return TRUE if all is well, and
- * FALSE on error (cannot create).
- */
- ffwopen(fn)
- char *fn;
- {
- #if BFILES
- #if AtST
- register int i;
-
- if ((i = creat(fn, 0x00)) < 0)
- return (FIOERR);
- hndl = i;
- fbpos = fbufp;
- ftail = fbufp + FBLOCK;
- return (FIOSUC);
- #else
- return (FIOERR);
- #endif AtST
- #else
- #if VMS
- register int fd;
-
- if ((fd=creat(fn, 0666, "rfm=var", "rat=cr")) < 0
- || (ffp=fdopen(fd, "w")) == NULL)
- return (FIOERR);
- #else
- if ((ffp=fopen(fn, "w")) == NULL)
- return (FIOERR);
- #endif VMS
- return (FIOSUC);
- #endif BFILES
- }
-
- /*
- * Close an input file.
- */
- frclose()
- {
- #if BFILES
- close(hndl);
- #else
- fclose(ffp);
- #endif
- }
-
- /*
- * Close an output file.
- * Should look at the status in all systems.
- */
- fwclose()
- {
- #if BFILES
- register int size;
-
- size = ((int) (fbpos - fbufp));
- if (size > 0) /* something to write out */
- {
- if (write(hndl, fbufp, size) != size)
- {
- mlwrite("Write error");
- return (FIOERR);
- }
- }
- if (close(hndl) < 0)
- {
- mlwrite("Error closing file");
- return(FIOERR);
- }
- #else
- #if V7
- if (fclose(ffp) != FALSE)
- {
- mlwrite("Error closing file");
- return(FIOERR);
- }
- #else
- #if AtST
- if (ffp != NULL && fclose(ffp) != FALSE)
- {
- mlwrite("Error closing file");
- return (FIOERR);
- }
- #else
- fclose(ffp);
- #endif AtST
- #endif V7
- #endif BFILES
- return (FIOSUC);
- }
-
- #if BFILES
- bputc(c)
- register int c;
- {
- if (fbpos >= ftail) /* ram full, write it out */
- {
- if (write(hndl, fbufp, FBLOCK) != FBLOCK)
- return (EOF);
- fbpos = fbufp;
- }
- *fbpos++ = (char) c;
- return (c);
- }
- #endif BFILES
-
- /*
- * Write a line to the already
- * opened file. The "buf" points to the
- * buffer, and the "nbuf" is its length, less
- * the free newline. Return the status.
- * Check only at the newline.
- */
- ffputline(buf, nbuf)
- register char buf[];
- register int nbuf;
- {
- register int i, c;
-
- c = 0; /* in case nbuf==0 */
- for (i=0; i<nbuf; ++i)
- {
- #if BFILES
- c = bputc(buf[i]);
- #else
- c = putc(buf[i], ffp);
- #endif
- if (c == EOF)
- break;
- }
- #if BFILES
- if (c != EOF)
- c = bputc('\r');
- if (c != EOF)
- c = bputc('\n');
- if (c==EOF)
- {
- #else
- if (c != EOF)
- c = putc('\n', ffp);
- if (c==EOF || ferror(ffp) != FALSE) {
- #endif
- mlwrite("Write error");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Read a line from a file,
- * and store the bytes in the supplied
- * buffer. The "nbuf" is the length of the
- * buffer. Complain about long lines and lines
- * at the end of the file that don't have a
- * newline present. Check for I/O errors
- * too. Return status.
- */
- ffgetline(buf, nbuf)
- register char buf[];
- register int nbuf;
- {
- register int c, i;
- #if BFILES
- int size = 1;
- #endif
- i = 0;
- --nbuf;
- #if BFILES
- for(;;)
- {
- if (fbpos >= ftail)
- {
- size = read(hndl, fbufp, FBLOCK);
- fbpos = fbufp;
- ftail = fbufp + size;
- if (fbpos >= ftail)
- {
- c = EOF;
- break;
- }
- }
- c = *fbpos++;
- if (c == '\r')
- continue; /* go get the '\n' */
- if (c == '\n')
- break;
- #else
- while ((c=getc(ffp))!=EOF && c!='\n')
- {
- if (c == '\r')
- {
- if ((c=getc(ffp)) != '\n')
- {
- ungetc(c, ffp);
- c = '\n'; /* this should work */
- } /* on all systems! */
- }
- #endif BFILES
- buf[i++] = c;
- if (i >= nbuf)
- {
- mlwrite("File has long line: splitted");
- break;
- }
- }
- buf[i] = 0;
- if (c == EOF)
- {
- #if BFILES
- if (size != 0)
- {
- #else
- if (ferror(ffp) != FALSE)
- {
- #endif
- mlwrite("File read error");
- return (FIOERR);
- }
- if (i != 0)
- {
- mlwrite("Added newline at EOF");
- return (FIOFNF); /* dal: indicate nl missing */
- }
- return (FIOEOF);
- }
- return (FIOSUC);
- }
-
- /*
- * file: spawn.c
- *
- * The routines in this file
- * are called to create a subjob running
- * a command interpreter. This code is a big
- * fat nothing on CP/M-86. You lose.
- * dal: added single program execution for AtST
- * dal: added built in command shell for AtST
- * dal: removed internal shell and added support for system() call
- * in dLibs, which handles _shell_p, etc.
- */
-
- #if VMS
- #define EFN 0 /* Event flag. */
-
- #include <ssdef.h> /* Random headers. */
- #include <stsdef.h>
- #include <descrip.h>
- #include <iodef.h>
-
- extern int oldmode[]; /* In "termio.c" */
- extern int newmode[]; /* In "termio.c" */
- extern short iochan; /* In "termio.c" */
- #endif
-
- #if MSDOS
- #include <dos.h>
- #endif
-
- #if V7
- #include <signal.h>
- #endif
-
- /*
- * Create a subjob with a copy
- * of the command intrepreter in it. When the
- * command interpreter exits, mark the screen as
- * garbage so that you do a full repaint. Bound
- * to "C-C". The message at
- * the start in VMS puts out a newline. Under
- * some (unknown) condition, you don't get one
- * free when DCL starts up.
- */
- spawncli(f, n)
- {
- #if V7
- register char *cp;
- char *getenv();
- #endif
- #if VMS
- movecursor(term.t_nrow, 0); /* In last line. */
- mlputs("[Starting DCL]\r\n");
- (*term.t_flush)(); /* Ignore "ttcol". */
- sgarbf = TRUE;
- return (sys(NULL)); /* NULL => DCL. */
- #endif
- #if AtST
- mouse_dead(); /* no mouse cursor motion */
- movecursor(term.t_nrow, 0);
- (*term.t_putchar)('\r');
- (*term.t_putchar)('\n');
- (*term.t_flush)();
- shell();
- sgarbf = TRUE;
- mouse_live(); /* reactivate mouse cursor */
- return(TRUE);
- #endif
- #if CPM
- mlwrite("Can't spawn a shell in CP/M-86");
- return (FALSE);
- #endif
- #if MSDOS
- movecursor(term.t_nrow, 0); /* Seek to last line. */
- (*term.t_flush)();
- sys("\\command.com", ""); /* Run CLI. */
- sgarbf = TRUE;
- return(TRUE);
- #endif
- #if V7
- movecursor(term.t_nrow, 0); /* Seek to last line. */
- (*term.t_flush)();
- ttclose(); /* stty to old settings */
- if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
- system(cp);
- else
- system("exec /bin/sh");
- sgarbf = TRUE;
- sleep(2);
- ttopen();
- return(TRUE);
- #endif
- }
-
- /*
- * Run a one-liner in a subjob.
- * When the command returns, wait for a single
- * character to be typed, then mark the screen as
- * garbage so a full repaint is done.
- * Bound to "C-X !".
- */
- spawn1(f, n)
- {
- register int s;
- char line[NLINE];
-
- #if VMS
- if ((s=mlreply("DCL command: ", line, NLINE)) != TRUE)
- return (s);
- (*term.t_putchar)('\n'); /* Already have '\r' */
- (*term.t_flush)();
- s = sys(line); /* Run the command. */
- mlputs("\r\n\n[End]"); /* Pause. */
- (*term.t_flush)();
- while ((*term.t_getchar)() != '\r')
- ;
- sgarbf = TRUE;
- return (s);
- #endif
- #if AtST
- if ((s=mlgets("Shell command", NULL, line, NLINE, CRLF)) == ABORT)
- return (s);
- if (*line)
- {
- (*term.t_putchar)('\n'); /* Already have '\r' */
- (*term.t_flush)();
- mouse_dead(); /* no mouse cursor motion */
- s = system(line);
- mlwrite( "Hit [RETURN] to re-enter MicroEMACS..." );
- while ((*term.t_getchar)() != '\r')
- ;
- mouse_live(); /* reactivate mouse cursor */
- sgarbf = TRUE;
- if(s != 0)
- {
- mlpending( "Exit code %d", s);
- return(FALSE);
- }
- return(TRUE);
- }
- return(FALSE);
- #endif
- #if CPM
- mlwrite("No command exec for CP/M-86");
- return (FALSE);
- #endif
- #if MSDOS
- if ((s=mlreply("MS-DOS command: ", line, NLINE)) != TRUE)
- return (s);
- system(line);
- mlwrite( "Hit [RETURN] to re-enter MicroEMACS..." );
- while ((*term.t_getchar)() != '\r') /* Pause. */
- ;
- sgarbf = TRUE;
- return (TRUE);
- #endif
- #if V7
- if ((s=mlreply("! ", line, NLINE)) != TRUE)
- return (s);
- (*term.t_putchar)('\n'); /* Already have '\r' */
- (*term.t_flush)();
- ttclose(); /* stty to old modes */
- system(line);
- sleep(2);
- ttopen();
- mlputs("[End]"); /* Pause. */
- (*term.t_flush)();
- while ((s = (*term.t_getchar)()) != '\r' && s != ' ')
- ;
- sgarbf = TRUE;
- return (TRUE);
- #endif
- }
-
- #if VMS
- /*
- * Run a command. The "cmd" is a pointer
- * to a command string, or NULL if you want to run
- * a copy of DCL in the subjob (this is how the standard
- * routine LIB$SPAWN works. You have to do wierd stuff
- * with the terminal on the way in and the way out,
- * because DCL does not want the channel to be
- * in raw mode.
- */
- sys(cmd)
- register char *cmd;
- {
- struct dsc$descriptor cdsc;
- struct dsc$descriptor *cdscp;
- long status;
- long substatus;
- long iosb[2];
-
- status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
- oldmode, sizeof(oldmode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- return (FALSE);
- cdscp = NULL; /* Assume DCL. */
- if (cmd != NULL) /* Build descriptor. */
- {
- cdsc.dsc$a_pointer = cmd;
- cdsc.dsc$w_length = strlen(cmd);
- cdsc.dsc$b_dtype = DSC$K_DTYPE_T;
- cdsc.dsc$b_class = DSC$K_CLASS_S;
- cdscp = &cdsc;
- }
- status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
- if (status != SS$_NORMAL)
- substatus = status;
- status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
- newmode, sizeof(newmode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- return (FALSE);
- if ((substatus&STS$M_SUCCESS) == 0) /* Command failed. */
- return (FALSE);
- return (TRUE);
- }
- #endif
-
- #if MSDOS
- /*
- * This routine, once again
- * by Bob McNamara, is a C translation
- * of the "system" routine in the MWC-86 run
- * time library. It differs from the "system" routine
- * in that it does not unconditionally append the
- * string ".exe" to the end of the command name.
- * We needed to do this because we want to be
- * able to spawn off "command.com". We really do
- * not understand what it does, but if you don't
- * do it exactly "malloc" starts doing very
- * very strange things.
- */
- sys(cmd, tail)
- char *cmd;
- char *tail;
- {
- register unsigned n;
- extern char *__end;
-
- n = __end + 15;
- n >>= 4;
- n = ((n + dsreg() + 16) & 0xFFF0) + 16;
- return(execall(cmd, tail, n));
- }
- #endif
-
- #if AtST
- static char *_fn_lst = NULL;
-
- /*
- * dal: This routine builds the directory text
- * in the special secret buffer. It is called
- * by mlgetfn() via make_popup(). Returns TRUE
- * if everything works. Returns FALSE if there
- * is an error (if there is no memory).
- */
- make_dir(buffer, data)
- BUFFER *buffer;
- char *data; /* dal: cheat a bit here... */
- {
- register char *p, *q;
- register int i, n;
- register long tsize;
- char line[128];
- struct stat dir, *oldirp;
-
- bbclear(buffer); /* Blow old text away */
- n = 0;
- sprintf(line, "\tDirectory of %s", data);
- if(_fn_lst)
- free(_fn_lst);
- _fn_lst = strdup(data);
- if(_fn_lst && (p = strrpbrk(_fn_lst, "\\:")))
- {
- *p++ = '\0';
- *p = '\0';
- }
- if (addline(line, buffer) == FALSE)
- return(FALSE);
- oldirp = Fgetdta();
- Fsetdta(&dir);
- if(Fsfirst(data, 0x10) == 0) /* include sub-directories */
- do
- {
- if(dir.st_mode == S_IFDIR) /* directory entry */
- {
- p = dir.st_name;
- if(!strcmp(p, ".") || !strcmp(p, ".."))
- continue;
- sprintf(line, "\t<DIR> %s\\", p);
- }
- else
- {
- ++n;
- tsize += dir.st_size;
- sprintf(line, "\t%6ld %s",
- dir.st_size, dir.st_name);
- if(_fn_lst)
- {
- i = ((int) msize(_fn_lst));
- _fn_lst = realloc(_fn_lst, i+16);
- if(_fn_lst)
- {
- p = strrchr(_fn_lst, '\0');
- *p++ = '|';
- strcpy(p, dir.st_name);
- }
- }
- }
- if (addline(line, buffer) == FALSE)
- {
- Fsetdta(oldirp);
- return(FALSE);
- }
- }
- while(Fsnext() == 0);
- Fsetdta(oldirp);
- sprintf(line, "\t%5d files (%ld bytes).", n, tsize);
- if (addline(line, buffer) == FALSE)
- return(FALSE);
- return (TRUE); /* All done */
- }
- #endif AtST
-
- /*
- * dal: Get a file name from the user.
- * If the string contains wildcard characters,
- * give a directory of files matching the
- * file spec and re-prompt until a valid
- * non-ambiguous file name is obtained.
- */
- mlgetfn(prompt, buf, len)
- char *prompt, *buf;
- int len;
- {
- register int s, popped = FALSE;
- char tmp[128], *p = NULL, *q = NULL, *r;
-
- #if AtST
- p = NULL;
- for(;;)
- {
- if((s=mlgets(prompt, p, buf, len, "\r\n+-")) == ABORT)
- {
- if(popped)
- onlywind(FALSE,1);
- return(s);
- }
- if((buf[0] == '\0') && p) /* default */
- strcpy(buf, p);
- if(popped && q)
- {
- if(s == '+')
- {
- if((q = strchr(q, '|')) == NULL)
- q = strchr(_fn_lst, '\0');
- goto MAKE_FN;
- }
- if(s == '-')
- {
- if(*--q == '\0') {
- p = strrchr(q+1, '|');
- if(p)
- q = p;
- }
- else
- while((*--q) && (*q != '|'))
- ;
- goto MAKE_FN;
- }
- }
- else if((s == '+') || (s == '-'))
- continue;
- if(!(strchr(buf, '*') || strchr(buf, '?'))) /* no wildcards */
- return(popped ? onlywind(FALSE,1) : TRUE);
- fullpath(buf, buf);
- if ((s=make_popup(bdirp, make_dir, buf)) != TRUE)
- return(s);
- if(q = strchr(_fn_lst, '|'))
- *q = '\0';
- if(q == NULL)
- q = strchr(_fn_lst, '\0');
- popped = TRUE;
- MAKE_FN: p = strcpy(tmp, _fn_lst);
- r = strrchr(p, '\0');
- *r++ = '\\';
- memccpy(r, ++q, '|', 16);
- if(r = strchr(r, '|'))
- *r = '\0';
- update();
- }
- #else
- return(mlgets(prompt, NULL, buf, len, CRLF) != ABORT);
- #endif
- }
-